import {
  Injectable,
  NotFoundException,
  BadRequestException,
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Post, PostComment,PostLike } from './post.entity';
import { Notification } from '../notification/notification.entity';
import { NotificationService } from '../notification/notification.service';
import { NotificationType } from '../notification/notification.entity';
import {
  CreatePostDto,
  UpdatePostDto,
  CreatePostCommentDto,
} from './dto/create-post.dto';

@Injectable()
export class PostService {
  constructor(
    @InjectRepository(Post)
    private postRepository: Repository<Post>,
    @InjectRepository(PostComment)
    private postCommentRepository: Repository<PostComment>,
    @InjectRepository(PostLike)
    private postLikeRepository: Repository<PostLike>,
    @InjectRepository(Notification)
    private notificationRepository: Repository<Notification>,
    private readonly notificationService: NotificationService,
  ) {}

  async create(createPostDto: CreatePostDto, userId: number): Promise<Post> {
    const post = this.postRepository.create({
      ...createPostDto,
      userId,
      images: createPostDto.images?.join(','),
    });
    return this.postRepository.save(post);
  }

  async findAll(query: any, userId?: number): Promise<[Post[], number]> {
    //categoryId 0 全部 1推荐 2最新 3热门
    const { page = 1, pageSize = 10, keyword, categoryId } = query;
    const skip = (page - 1) * pageSize;

    const qb = this.postRepository
      .createQueryBuilder('post')
      .leftJoinAndSelect('post.user', 'user')
      .leftJoinAndSelect('post.comments', 'comments')
      .leftJoinAndSelect('comments.user', 'commentUser')
      .loadRelationCountAndMap('post.commentCount', 'post.comments')
      .groupBy('post.id, user.id, comments.id, commentUser.id');

    if (keyword) {
      qb.andWhere('(post.title LIKE :keyword OR post.content LIKE :keyword)', {
        keyword: `%${keyword}%`,
      });
    }
    if (categoryId) {
      if (categoryId == 1) {
        qb.orderBy('post.likes', 'DESC');
      } else if (categoryId == 2) {
        qb.orderBy('post.createdAt', 'DESC');
      } else if (categoryId == 3) {
        qb.orderBy('post.views', 'DESC');
      } 
    } else {
      qb.orderBy('post.createdAt', 'DESC');
    }

    const [posts, total] = await qb
      .skip(skip)
      .take(pageSize)
      .getManyAndCount();


    // 添加是否点赞的状态
    if (userId) {
      const likedPosts = await this.postLikeRepository.find({
        where: { userId },
        select: ['postId']
      });
      const likedPostIds = likedPosts.map(like => like.postId);



      
      posts.forEach(post => {
        post['isLiked'] = likedPostIds.includes(post.id);
      });
    }

    return [posts, total];
}

  async findOne(id: number): Promise<Post> {
    const post = await this.postRepository.findOne({
      where: { id } as any ,
      relations: [
        'user',
        'comments',
        'comments.user',
        'comments.replies',
        'comments.replies.user',
        'comments.replies.replies',
        'comments.replies.replies.user',
      ],
    });

    if (!post) {
      throw new NotFoundException('帖子不存在');
    }

    // 增加浏览量
    post.views += 1;
    await this.postRepository.save(post);

    return post;
  }

  async update(
    id: number,
    updatePostDto: UpdatePostDto,
    userId: number,
  ): Promise<Post> {
    const post = await this.findOne(id);

    if (post.userId !== userId) {
      throw new BadRequestException('您没有权限修改此帖子');
    }

    Object.assign(post, updatePostDto);
    return this.postRepository.save(post);
  }

  async remove(id: number, userId: number): Promise<void> {
    const post = await this.findOne(id);

    if (post.userId !== userId) {
      throw new BadRequestException('您没有权限删除此帖子');
    }

    await this.postRepository.remove(post);
  }

  async like(postId: number, userId: number, username:string): Promise<PostLike> {
    const like = this.postLikeRepository.create({
      postId,
      userId,
    });
    const post = await this.postRepository.findOne({ where: { id: postId } });
    if (post) {
      post.likes += 1;
      await this.postRepository.save(post);
      
      // 添加通知
      await this.notificationService.create(
        NotificationType.POST_COMMENTED, 
        `用户${username}点赞了你的帖子`,
        post.userId,
        postId
      );
    }

    return this.postLikeRepository.save(like);
  }
  async unlike(postId: number, userId: number): Promise<void> {
    const like = await this.postLikeRepository.findOne({
      where: { postId, userId },
    });

    
    if (!like) {
      throw new BadRequestException('您还没有点赞过此帖子');
    }
    const post = await this.postRepository.findOne({ where: { id: postId } });
    if (post) {
      post.likes -= 1;
      await this.postRepository.save(post);
    }

    await this.postLikeRepository.remove(like);
  }
  async createComment(
    id: number,
    createCommentDto: CreatePostCommentDto,
    userId: number,
    username:string
  ): Promise<PostComment> {
    const post = await this.findOne(id);

    const comment = this.postCommentRepository.create({
      ...createCommentDto,
      postId: id,
      userId,
    });

    // 添加通知
    await this.notificationService.create(
      NotificationType.POST_LIKED,
      `用户${username}评论了你的帖子：${createCommentDto.content.substring(0, 20)}...`,
      post.userId,
      id
    );

    return this.postCommentRepository.save(comment);
  }

  async getMyPosts(userId: number): Promise<Post[]> {
    return this.postRepository.find({
      where: { userId },
      relations: ['comments'],
      order: { createdAt: 'DESC' },
    });
  }
  //获取我的所有评论
  async getMyComments(userId: number): Promise<PostComment[]> {
    return this.postCommentRepository.find({
      where: { userId },
      relations: ['post','user'],
      order: { createdAt: 'DESC' },
    });
  }
  //获取我的所有点赞过的帖子
  async getMyLikedPosts(userId: number): Promise<PostLike[]> {
    const likedPosts = await this.postLikeRepository.find({
      where: { userId },
      relations: ['post','user'],
    });

    return likedPosts;
  }
}
